package ar.edu.utn.frba.disenio.aerolineas;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.lanchita.AerolineaLanchita;
import com.lanchita.excepciones.LanchitaException;

import ar.edu.utn.frba.disenio.Asiento;
import ar.edu.utn.frba.disenio.Busqueda;
import ar.edu.utn.frba.disenio.DateParser;
import ar.edu.utn.frba.disenio.Escalador;
import ar.edu.utn.frba.disenio.ReservasManager;
import ar.edu.utn.frba.disenio.Usuario;
import ar.edu.utn.frba.disenio.Vuelo;
import ar.edu.utn.frba.disenio.exceptions.NoSePuedeComprarException;
import ar.edu.utn.frba.disenio.exceptions.NoSePuedeReservarException;



public class LanchitaAdapter implements Aerolinea {

	private AerolineaLanchita lanchita;
	private ReservasManager reservasManager = new ReservasManager();
	
	public LanchitaAdapter() {
		super();
		lanchita = AerolineaLanchita.getInstance();
	}
	
	public LanchitaAdapter(AerolineaLanchita mock) {
		super();
		lanchita = mock;
	}
	
	public String toString()
	{
		return "Lanchita";
	}

	@Override
	public List<Vuelo> asientosDisponibles(Usuario usuario,Busqueda busqueda)
	{
		List<Vuelo> vuelos = new ArrayList<Vuelo>();
		DateTimeFormatter dateFormat = DateTimeFormat.forPattern("dd/MM/YYYY");
		
		String fechaDeSalida = busqueda.getFecha().toString(dateFormat);
		
		List<Asiento> asientosDirectos = this.adaptarAsientos(lanchita.asientos(busqueda.getOrigen(),busqueda.getDestino(),fechaDeSalida,null,null,null),usuario);
		
		if(busqueda.isConEscalas())
		{
			List<Asiento> asientosOrigen = this.adaptarAsientos(lanchita.asientos(busqueda.getOrigen(),null,fechaDeSalida,null,null,null),usuario);
			List<Asiento> asientosIntermedios = this.adaptarAsientos(lanchita.asientos(null,null,null,null,null,null),usuario);
			List<Asiento> asientosDestino = this.adaptarAsientos(lanchita.asientos(null,busqueda.getDestino(),null,null,null,null),usuario);
			
			List<Vuelo> unaEscala = Escalador.unaEscala(asientosOrigen,asientosDestino);
			List<Vuelo> dosEscalas = Escalador.dosEscalas(asientosOrigen,asientosIntermedios,asientosDestino);
			
			
			vuelos.addAll(unaEscala);
			vuelos.addAll(dosEscalas);
		}
		
		List<Vuelo> sinEscalas = Escalador.sinEscala(asientosDirectos);
		vuelos.addAll(sinEscalas);
		
		return vuelos;
		
	}
	
	private List<Asiento> adaptarAsientos(String[][] asientosLanchita, Usuario usuario)
	{
		List<Asiento> asientos = new ArrayList<Asiento>();
		
		for (String[] asientoArray : asientosLanchita)
		{
			String[] codigoYasiento = asientoArray[0].split("-");
			
			Asiento asiento = new Asiento();
			asiento.setAerolinea(this);
			asiento.setCodigoVuelo(codigoYasiento[0]);
			asiento.setNumeroAsiento(Integer.parseInt(codigoYasiento[1]));
			asiento.setPrecio(new BigDecimal(asientoArray[1]),this.getPorcentajeImpuestos(),usuario.getAdicionalPorTipo());
			asiento.setClase(asientoArray[2]);
			asiento.setUbicacion(asientoArray[3]);
			asiento.setReservado(asientoArray[4] == "R" ? true : false);
			asiento.setLlegada(DateParser.parseaFlexiblemente(asientoArray[11]+" "+asientoArray[7]));
			asiento.setSalida(DateParser.parseaFlexiblemente(asientoArray[10]+" "+asientoArray[6]));
			asiento.setOrigen(asientoArray[8]);
			asiento.setDestino(asientoArray[9]);
			
			//No agrega los que tienen estado Comprado
			if(asientoArray[4] != "C")
				asientos.add(asiento);
		}
		
		return asientos;
	}

	@Override
	public void comprarAsiento(Usuario usuario,Asiento asiento) {
		try
		{	
			this.reservasManager.controlDeVentaDeReserva(asiento,usuario);
			this.lanchita.comprar(asiento.getCodigo());
			this.reservasManager.comprarReserva(asiento, usuario);
		} catch (LanchitaException ex)
		{
			throw new NoSePuedeComprarException(ex.getMessage());
		}
	}

	@Override
	public void reservarAsiento(Usuario usuario,Asiento asiento)
	{	
		reservasManager.ValidarReserva(asiento, usuario);
		
		try 
		{
			this.lanchita.reservar(asiento.getCodigo(), usuario.getDni().toString());
			this.reservasManager.reservar(asiento, usuario);
		} 
		catch (LanchitaException ex)
		{
			throw new NoSePuedeReservarException(ex.getMessage());
		}
	}
	
	@Override
	public void sobrereservarAsiento(Usuario usuario,Asiento asiento)
	{
		this.reservasManager.ValidarSobrereserva(asiento, usuario);
		this.reservasManager.sobrereservar(asiento, usuario);
	}
	
	@Override
	public BigDecimal getPorcentajeImpuestos() {
		return new BigDecimal(0.15);
	}

	public ReservasManager getReservasManager() {
		return reservasManager;
	}

	public void setReservasManager(ReservasManager reservasManager) {
		this.reservasManager = reservasManager;
	}

	@Override
	public void cancelarReserva(Asiento asiento, Usuario usuario) {
		this.reservasManager.cancelarReservacion(asiento, usuario);
		
	}
}
